#include "GTask.h"
#include "GError.h"
#include "GTaskResult.h"
#include "GTaskManager.h"

namespace GEngine
{
	G_DEFINE_DEBUG_NAME(GTask);

	// Description: Constructor
	// Return:
	// Notes: TaskResult is the object that will be used to track this tasks state and result.
	// Notes: TaskPriority is the priority of task. Higher priority means sooner execution.
	// Notes: TaskThreadSafe indicates that task can run on any core. Otherwise tasks only runs on the core it is scheduled.
	// ----------------------------------------------------
	GTask::GTask(GTaskResult* TaskResult, GTaskPriority TaskPriority, bool TaskThreadSafe)
	{
		Result = TaskResult;
		Priority = TaskPriority;
		ThreadSafe = TaskThreadSafe;
	}

	// Description: Destructor
	// Return:
	// Notes:
	// ----------------------------------------------------
	GTask::~GTask()
	{
	}

	// Description: Returns the task result.
	// Return:
	// Notes:
	// ----------------------------------------------------
	GTaskResult* GTask::GetResult()
	{
		return Result;
	}

	// Description: Returns the task priority
	// Return:
	// Notes:
	// ----------------------------------------------------
	GTaskPriority GTask::GetPriority() const
	{
		return Priority;
	}

	// Description: Increases the referance count of this task
	// Return:
	// Notes: Used internally when a new task is spawned/registered
	// ----------------------------------------------------
	void GTask::IncreaseRef()
	{
		Result->IncreaseRef();
	}

	// Description: Decreases the referance count of this task
	// Return:
	// Notes: Used internally when a task is completed
	// ----------------------------------------------------
	void GTask::DecreaseRef()
	{
		Result->DecreaseRef();
	}

	// Description: Returns if task is thread safe or not
	// Return:
	// Notes: Thread safe means task can run on any thread
	// ----------------------------------------------------
	bool GTask::CheckThreadSafe() const
	{
		return ThreadSafe;
	}

	// Description: Distribute task to threads.
	// Return: True if task is distributed, false otherwise.
	// Notes: Used by manager for better utilization.
	// Notes: Expected to be overriden by user.
	// Notes: Try to distribute evenly.
	// Notes: Generally a new task for each core is enough.
	// Notes: Do not spread if not thread safe
	// ---------------------------------------------------
	bool GTask::Spread(GTaskQueue** QueueArr, GSize Count)
	{
		return false;
	}

	// Description: Creates a new task which is a small fraction of this task.
	// Return: True if task is reduced, false otherwise.
	// Notes: Workers reduces and executes the new task until task is complete
	// Notes: Used by manager for better utilization.
	// Notes: Expected to be overriden by user.
	// Notes: Try not to reduce more than granularity.
	// ---------------------------------------------------
	bool GTask::Reduce(OUTPUT GTask** OutTask)
	{
		return false;
	}

	// Description: Creates a new task with the half of the available work.
	// Return: True if task is divided, false otherwise.
	// Notes: Used when stealing from other queues.
	// Notes: Used by manager for better utilization.
	// Notes: Expected to be overriden by user.
	// Notes: Try to divide into two equal parts.
	// Notes: Do not divide if not thread safe
	// ---------------------------------------------------
	bool GTask::Divide(OUTPUT GTask** OtherHalf)
	{
		return false;
	}
}